﻿using GrapeCity.Forguncy.CellTypes;
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Windows;
using Vant.Properties;
using Vant.WpfControls;
using Vant.WpfControls.DrawingObject;

namespace Vant.CellTypes
{
    public class GridDesigner : CellTypeDesigner<Grid>, ISupportPropertyInitialize, ISupportStyleInitialize
    {
        public Dictionary<StylePropertyName, object> GetDefaultStyleInfos(ICellInfo cellInfo)
        {
            return new Dictionary<StylePropertyName, object> { { StylePropertyName.FontSize, 12 } };
        }

        public override FrameworkElement GetDrawingControl(ICellInfo cellInfo, IDrawingHelper drawingHelper)
        {
            var cellStyleViewModel = StyleHelper.CreateStyleViewModel(cellInfo, drawingHelper);
            return new GridDrawingObject(this.CellType, cellStyleViewModel, cellInfo, drawingHelper);
        }

        public void InitDefaultPropertyValues(IBuilderContext context)
        {
            for (int i = 0; i < 8; i++)
            {
                this.CellType.options.Add(new GridItem()
                {
                    value = (i + 1).ToString(),
                    text = Properties.Resources.Grid_GridItem_Text + (i + 1).ToString(),
                    icon = new ImageValue()
                    {
                        Name = "Navigation/175_image_3.svg",
                        BuiltIn = true,
                        Color = "Text 1 25",
                    }
                });
            }
        }
    }

    [Designer("Vant.CellTypes.GridDesigner, Vant")]
    [Icon("pack://application:,,,/Vant;component/Resources/Images/Grid.png")]
    [OrderWeight((int)Utils.OrderWeight.Grid)]
    public class Grid : VantCellTypeBase, ISupportUIPermission
    {
        [SRDisplayName(nameof(Resources.EditCommand))]
        [SRCustomCommandObject(InitParamProperties = "value|text", InitParamValues = nameof(Resources.Grid_EditCommand_InitParamValues))]
        public object ClickCommand { get; set; }

        [SRDisplayName(nameof(Resources.UseBinding))]
        [BoolProperty]
        [MergableProperty(false)]
        public bool useBinding { get; set; } = false;

        [SRDisplayName(nameof(Resources.Grid_Options))]
        [SRObjectListProperty(IndentLevel = 1, ItemType = typeof(GridItem), DefaultName = nameof(Resources.Grid_Options_DefaultName))]
        public List<INamedObject> options { get; set; } = new List<INamedObject>();

        [SRDisplayName(nameof(Resources.BindingOptions))]
        [SRBindingDataSourceProperty(Columns = nameof(Resources.Grid_Options_BindingOptions_Columns), IndentLevel = 1)]
        public object bindingOptions { get; set; }

        [SRRadioGroupProperty(ValueList = "horizontal|vertical", DisplayList = nameof(Resources.Grid_Direction_RadioGroupProperty_DisplayList))]
        [SRDisplayName(nameof(Resources.Grid_Direction))]
        public string direction { get; set; } = "vertical";

        [SRDisplayName(nameof(Resources.Grid_Direction_ColumnNum))]
        [IntProperty(Min = 1, Max = 50)]
        [DefaultValue(4)]
        public int columnNum { get; set; } = 4;

        [SRDisplayName(nameof(Resources.IconSize))]
        [IntProperty(Min = 5)]
        [DefaultValue(28)]
        public int iconSize { get; set; } = 28;

        [SRDisplayName(nameof(Resources.Grid_Direction_Gutter))]
        [IntProperty(Min = 0)]
        [DefaultValue(0)]
        public int gutter { get; set; } = 0;

        [SRCategoryHeader(nameof(Resources.Other))]
        [SRDisplayName(nameof(Resources.Grid_Direction_Border))]
        [DefaultValue(true)]
        public bool border { get; set; } = true;

        [SRDisplayName(nameof(Resources.Grid_Direction_Center))]
        [DefaultValue(true)]
        public bool center { get; set; } = true;

        [SRDisplayName(nameof(Resources.Grid_Direction_Square))]
        public bool square { get; set; } = false;

        [SRDisplayName(nameof(Resources.Grid_Direction_Reverse))]
        public bool reverse { get; set; } = false;

        [Browsable(false)]
        [SaveJsonIgnore]
        [PageMetadataJsonIgnore]
        public List<UIPermission> UIPermissions
        {
            get 
            {
                if (useBinding)
                {
                    return new List<UIPermission>();
                }
                var permission = new UIPermission()
                {
                    Scope = UIPermissionScope.Visible,
                    Enabled = true,
                    Ignore = true,
                    AllowRoles = new List<string>() { DefaultRoleManager.FGC_Anonymous },
                    Children = this.options.OfType<GridItem>().Select(item => new SubUIPermission() 
                    {
                        Name = item.text,
                        AllowRoles = item.CanVisitRoleList.Any() ? item.CanVisitRoleList.Select(r => r).ToList() : new List<string> { DefaultRoleManager.FGC_Anonymous }
                    }).ToList()
                };

                return new List<UIPermission>() { permission };
            }
            set 
            {
                //When get server ui permissions will set values
                var visiblePermission = value?.FirstOrDefault(item => item.Scope == UIPermissionScope.Visible);
                if (visiblePermission == null)
                {
                    return;
                }

                this.options?.OfType<GridItem>().ToList().ForEach(item =>
                {
                    var permission = visiblePermission.Children.FirstOrDefault(p => p.Name == item.text);
                    if (permission == null)
                    {
                        return;
                    }

                    item.CanVisitRoleList.Clear();
                    var allowRoles = permission.AllowRoles;
                    if (allowRoles != null)
                    {
                        item.CanVisitRoleList.AddRange(allowRoles.Select(r => r));
                    }
                });
            }
        }

        [RunTimeMethod]
        [SRDisplayName(nameof(Resources.RunTimeMethod_SetBadge))]
        public void SetBadge(
            [SRItemDisplayName(nameof(Resources.RunTimeMethod_SetBadge_itemValue))]
            string itemValue,
            [SRItemDisplayName(nameof(Resources.RunTimeMethod_SetBadge_badgeValue))]
            string badgeValue)
        {

        }

        public override string ToString()
        {
            return Properties.Resources.Grid;
        }

        public override bool GetDesignerPropertyVisible(string propertyName)
        {
            if (propertyName == nameof(options))
            {
                return !useBinding;
            }
            if (propertyName == nameof(bindingOptions))
            {
                return useBinding;
            }
            return base.GetDesignerPropertyVisible(propertyName);
        }
    }

    public class GridItemDesigner : ObjectDesigner
    {
        public override EditorSetting GetEditorSetting(PropertyDescriptor property, IBuilderContextBase contextBase)
        {
            if (property.Name == nameof(GridItem.CanVisitRoleList))
            {
                return new RolePermissionEditorSetting();
            }

            return base.GetEditorSetting(property, contextBase);
        }
    }

    [Designer("Vant.CellTypes.GridItemDesigner, Vant")]
    public class GridItem : ObjectPropertyBase, INamedObject
    {
        public GridItem()
        {
            CanVisitRoleList = new List<string>()
            {
                DefaultRoleManager.FGC_Anonymous
            };
        }

        [SRDisplayName(nameof(Resources.Value))]
        [Required]
        public string value { get; set; }

        [SRDisplayName(nameof(Resources.Label))]
        [Required]
        public string text { get; set; }

        [SRDisplayName(nameof(Resources.Icon))]
        [IconProperty(DefaultIconColor = "Text 1 25")]
        public ImageValue icon { get; set; }

        [SRDisplayName(nameof(Resources.Grid_GridItem_BadgeStyle))]
        [SRComboProperty(ValueList = "badge|dot", DisplayList = nameof(Resources.Grid_GridItem_ComboProperty_DisplayList))]
        public string badgeStyle { get; set; } = "badge";

        [Browsable(false)]
        [SaveJsonIgnore]
        public bool dot
        {
            get
            {
                return badgeStyle == "dot";
            }
        }

        [SRDisplayName(nameof(Resources.Grid_GridItem_Badge))]
        [FormulaProperty]
        public object badge { get; set; }

        string INamedObject.Name
        {
            get => text;
            set
            {
                text = value;
            }
        }

        private List<string> _canVisitRoleList;

        [PageMetadataJsonIgnore]
        [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
        [SRDisplayName(nameof(Resources.Permission))]
        public List<string> CanVisitRoleList
        {
            get
            {
                if (_canVisitRoleList == null)
                {
                    _canVisitRoleList = new List<string>();
                }

                return _canVisitRoleList;
            }
            set
            {
                if (value == null || !value.Any())
                {
                    _canVisitRoleList = new List<string>()
                    {
                        DefaultRoleManager.FGC_Anonymous
                    };
                }
                else
                {
                    _canVisitRoleList = value;
                }
            }
        }
    }

    public class DefaultRoleManager
    {
        public static readonly string FGC_Anonymous = "FGC_Anonymous";
        public static readonly string FGC_LoginUser = "FGC_LoginUser";
    }
}
